/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package Proxy;

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.MulticastSocket;
import java.net.SocketException;
import java.net.UnknownHostException;
import java.util.concurrent.TimeoutException;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 *
 * @author Murilo
 */
public class ThreadProxy extends Thread {

    private DatagramPacket requisicaoCliente;
    private MulticastSocket socketGrupo;
    private InetAddress IpGrupo;
    private int portaGrupo;
    //socket para receber os dados do servidor que contenha o objeto
    private DatagramSocket socketRecebimentoServidor;
    
    //socket e porta para responder o cliente
    private DatagramSocket socketRespostaCliente;
    private int portaRespostaCliente;
    private InetAddress IpCliente;

    public ThreadProxy(DatagramPacket requisicaoCliente) throws UnknownHostException, IOException {
        this.requisicaoCliente = requisicaoCliente;
        this.socketGrupo = new MulticastSocket();
        this.IpGrupo = InetAddress.getByName("224.0.0.1");
        this.portaGrupo = 2001;
        this.socketRecebimentoServidor = new DatagramSocket();
        this.socketRespostaCliente = new DatagramSocket();
    }

    public String receberObjetoCliente(){
        String requisicaoCliente = new String(this.requisicaoCliente.getData(), this.requisicaoCliente.getOffset(),
                this.requisicaoCliente.getLength());
        String[] dadosCliente = requisicaoCliente.split("/");
        this.portaRespostaCliente = Integer.valueOf(dadosCliente[1]);
        System.out.println(this.requisicaoCliente.getAddress());
        
        //guarda o ip do cliente para devolver o objeto
        this.IpCliente = this.requisicaoCliente.getAddress();
        System.out.println("Objeto recebido do Cliente: " + dadosCliente[0]);
        return dadosCliente[0];
    }

    public void requisitarObjetoServidores() throws IOException {
        String dadosServidorProxy = receberObjetoCliente() + "/" + this.socketRecebimentoServidor.getLocalPort();
        byte[] buffer = dadosServidorProxy.getBytes();
        DatagramPacket requisicaoServidorProxy = new DatagramPacket(buffer, buffer.length, this.IpGrupo,
                this.portaGrupo);
        this.socketGrupo.send(requisicaoServidorProxy);
        
    }

    public void receberObjetoServidores() throws SocketException, IOException {
        DatagramPacket respostaServidores = new DatagramPacket(new byte[512], 512);
        this.socketRecebimentoServidor.setSoTimeout(100000);
        try {
            
            this.socketRecebimentoServidor.receive(respostaServidores);
            String dadosRespostaServidores = new String(respostaServidores.getData(), respostaServidores.getOffset(),
                    respostaServidores.getLength());
            System.out.println(respostaServidores.getAddress());
            System.out.println("Objeto recebido do Servidor: " + dadosRespostaServidores);
            
            //verifica a cache do proxy
            CacheProxy.insereObjetoCache(dadosRespostaServidores);
            
            this.responderCliente(dadosRespostaServidores);
            
            
            this.socketRecebimentoServidor.close();
        } catch (Exception ex) {
            System.out.println(ex.getMessage());
            this.responderCliente("Objeto não encontrado");
        }
    }
    
    public void responderCliente(String dadosServidores) throws IOException{
        byte[] buffer = dadosServidores.getBytes();
        DatagramPacket datagramaRespostaCliente = new DatagramPacket(buffer, buffer.length,
                this.IpCliente, this.portaRespostaCliente);
        this.socketRespostaCliente.send(datagramaRespostaCliente);
    }

    public void run() {
        try {
            this.requisitarObjetoServidores();
            this.receberObjetoServidores();
        } catch (IOException ex) {
            //se for erro de rede lançar aqui
            
            ex.printStackTrace();
        }
        
    }
}
